
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from py_at.adapters.TradeAdapter import TradeAdapter
from py_at.adapters.ctp_trade import CtpTrade
from py_at.adapters.ctp_quote import CtpQuote
from py_at.at_struct import InfoField,OrderField,TradeField
import json
import logging
import time
from datetime import datetime,timedelta
from py_at.data.readData import readData   #加载海风数据
from py_at.Enums import IntervalType
from py_at.at_struct import Tick
from py_at.Bar import *

class Account(TradeAdapter):
    '''多账户'''
    def __init__(self,Investor,Password,BrokerID,FrontID,QFrontID,):
        self.t = CtpTrade()
        self.q = CtpQuote()
        self.BrokerID=BrokerID
        self.FrontID=FrontID
        self.QFfontID=QFrontID
        self.Investor=Investor
        self.Password=Password
        self.Register()  #开始进行返回on函数注册


    def Register(self):
        """
        对所有的回调函数进行注册
        :return:
        """
        self.t.OnFrontConnected = self.OnFrontConnected
        self.t.OnRspUserLogin = self.OnRspUserLogin

        self.t.OnFrontDisConnected=self.OnFrontDisConnected

        self.q.OnFrontConnected = self.q_OnFrontConnected

        self.q.OnFrontDisConnected=self.q_OnFrontDisConnected
        self.t.ReqConnect(self.FrontID)


    def OnFrontConnected(self):
        """前置回调成功之后开始进行登陆"""
        print('{0}链接前置成功开始进行交易登陆'.format(self.Investor))
        self.t.ReqUserLogin(self.Investor, self.Password, self.BrokerID)

    def OnFrontDisConnected(self, error=0):
        """"""
        print('账户{0}交易服务器连接断开'.format(self.Investor))

    def OnRspUserLogin(self, info=InfoField):
        """"""
        print('{0}账户登陆完成 '.format(self.Investor))
        print("当前的资金情况%s" % self.t.Account)
        print("下面的实盘的实际仓位")
        print(self.t.DicPositionField)
        for te in self.t.DicPositionField:
            te = self.t.DicPositionField[te]

            #self.q.ReqSubscribeMarketData(te.InstrumentID)
            print('合约{0},方向{1},价格{2},持仓{3},昨仓{4},今仓{5},平仓利润{6},持仓利润{7},手续费{8},{9}'.format(te.InstrumentID, te.Direction,
                                                                                    te.Price, te.Position,
                                                                                    te.YdPosition, te.TdPosition,
                                                                                    te.CloseProfit,
                                                                                    te.PositionProfit,
                                                                                    te.Commission, te.Margin))


        #保存合约信息到json
        fileName='../DicInstrument.json'
        data={}
        for i in self.t.DicInstrument:
            data[i] = self.t.DicInstrument[i].__dict__
        with open(fileName, 'w') as f:
            json.dump(data,f)
        print('基础合约已经保存')


#行情 绑定
#--------------------------------------------------------------------------------------------------------------------------
    def q_OnFrontConnected(self):
        print('{0}行情链接'.format(self.Investor))
        self.q.ReqUserLogin(self.Investor, self.Password, self.BrokerID)

    def q_OnFrontDisConnected(self, error=0):
        print('账户{0}行情服务器连接断开'.format(self.Investor))





#-----------------------------------------------------------------------------------------------------------------------
#--------------------------------------------------------------------------------------------------------
    @staticmethod
    def read_data_test(stra):
        """取历史和实时K线数据,并执行策略回测"""
        # stra: Strategy = None  # 只为后面的提示信息创建

        print('策略 {0} 正在加载历史数据'.format(stra.ID))
        if stra.IntervalType == IntervalType.Tick:
            tradingday = stra.BeginDate
            tick:Tick = None
            while tradingday < time.strftime('%Y-%m-%d', time.localtime()):
                for tick in read_ticks(stra, tradingday):
                    for data in stra.Datas:
                        if data.Instrument == tick.Instrument:
                            data.on_tick(tick, tradingday)
                tradingday = datetime.strftime(datetime.strptime(tradingday, '%Y-%m-%d') + timedelta(days=1),
                                               '%Y-%m-%d')
        else:
            listBar = []
            bars = readData(stra)                  #读取数据库
            lasttime  = bars[-1]['DateTime']
            listBar = [
                Bar(b['DateTime'], b['High'], b['Low'], b['Open'], b['Close'], b['Volume'],
                    b['OpenInterest'], b['Tradingday'],b['Instrument']) for b in bars]

            for bar in listBar:
                for data in stra.Datas:
                    if data.Instrument == bar.Instrument:
                        # if bar.D[5:10]=='12-13':  对历史数据某天进行输出检查
                        #     print(bar)
                        data.__new_min_bar__(bar)  # 调Data的onbar

            # for data in stra.Datas:
            #     # data.__new_min_bar__(bar)  # 调Data的onbar   用1分钟数据的时候使用这个   否则使用下面的
            #
            #     data.Bars = np.append(data.Bars, bar)  # 对数据进行初始化填充
            #     data.D = np.append(data.D, bar.D.strftime('%Y%m%d %H:%M:%S'))
            #     data.H = np.append(data.H, bar.H)
            #     data.L = np.append(data.L, bar.L)
            #     data.O = np.append(data.O, bar.O)
            #     data.C = np.append(data.C, bar.C)
            #     data.V = np.append(data.V, bar.V)
            #     data.I = np.append(data.I, bar.I)
            #     date = bar.TD  # 原来是用真实日期做的HighD  现在更改为交易日期
            #     if len(data.DateD) == 0 or data.DateD[0] != date:
            #         data.DateD.insert(0, date)
            #         data.OpenD.insert(0, bar.O)
            #         data.HighD.insert(0, bar.H)
            #         data.LowD.insert(0, bar.L)
            #         data.CloseD.insert(0, bar.C)
            #     else:  # 如果还是当前天 那么就更新最高最低和收盘
            #         data.HighD[0] = max(data.HighD[0], bar.H)
            #         data.LowD[0] = min(data.LowD[0], bar.L)
            #         data.CloseD[0] = bar.C
            #
            #     data.BarUpdate(data, bar=bar)  # 传送到策略
        #stra.EnableOrder = True
        stra.Datas[0].CurrMin = lasttime


        #显示统计结果
        # statistics = Statistics(stra,self.allInstrument)  #计算结果
        # statistics.ShowWeb() #显示html网页


        #TODO 这个地方不应该盲目的注释掉  特别是下面的一条语句 stra.CurrMin 这个比较重要
        #print("orders:{0}, bars:{1}".format(len(stra.Orders), len(stra.Bars)))

                        # 生成策略的测试报告
        # Report(stra)       #显示回测

        # self.cfg.log.war("test history is end.")
        print("加载历史数据完成")